﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Schema;
using Microsoft.Xna.Framework.Input.Touch;

namespace OfficialGameProject {
	/// <summary>
	/// This class encapsulates all of the gameplay screen's logic
	/// </summary>
	class GameplayHandler : IXmlSerializable {
		//
		// Game Play Members
		//
		Rectangle gameWorldBounds;
		bool gameOver;
		Random random;

		//
		// Audio Members
		//
		SoundEffect enemyAttack;
		SoundEffect enemyDied;
		SoundEffect playerSlash;
		SoundEffect playerDied;

		//
		// Render Members
		//
		ContentManager contentManager;
		SpriteBatch spriteBatch;
		GraphicsDevice graphicsDevice;

		Texture2D enemyTexture;
		Texture2D background;
		Texture2D healthBar;

		SpriteFont coinFont;
		SpriteFont menuFont;

		Player player;
		List<Enemy> enemies;

		//
		//Input Member
		//
		TouchCollection touchCollection;
		Vector2 touchPosition;

		/// <summary>
		/// This constructor should only be used by the XML serializer.
		/// </summary>
		public GameplayHandler() {
			random = new Random();
			gameWorldBounds = new Rectangle(0, 0, 800, 640);
			gameOver = true;
			player = new Player();
			enemies = new List<Enemy>();
		}

		/// <summary>
		/// Creates a new instance of the game helper.
		/// </summary>
		/// <param name="contentManager">The content manager to use for loading the games content.</param>
		/// <param name="spriteBatch">The sprite batch to use for drawing the game's gameplay screen.</param>
		/// <param name="graphicsDevice">The graphics device on which the game is rendered.</param>
		public GameplayHandler(ContentManager contentManager, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice) {
			InitializeAssets(contentManager, spriteBatch, graphicsDevice);

			random = new Random();
			gameWorldBounds = new Rectangle(0, 0, 800, 600);
			gameOver = true;

			player = new Player();

			enemies = new List<Enemy>();
		}

		private void InitializeAssets(ContentManager contentManager, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice) {
			this.contentManager = contentManager;
			this.spriteBatch = spriteBatch;
			this.graphicsDevice = graphicsDevice;
		}

		//private void SetEnemiesTexture() {
		//    foreach (var enemy in enemies) {
		//        enemy.Texture = contentManager.Load<Texture2D>("Enemy");
		//    }
		//}

		/// <summary>
		/// Loads the content required for displaying the gameplay screen and starts the game.
		/// </summary>
		public void LoadContent() {
			background = contentManager.Load<Texture2D>("Background");
			healthBar = contentManager.Load<Texture2D>("HealthBar");
			enemyTexture = contentManager.Load<Texture2D>("Enemy");
			coinFont = contentManager.Load<SpriteFont>("SpriteFont1");
		}

		/// <summary>
		/// Unloads the game's particle system and saves the coins earned.
		/// </summary>
		public void UnloadContent() {
			//SaveCoin();

		}


		private void GenerateEnemies() {
			while (enemies.Count < 10) {
				var x = random.Next(0, 700);
				var y = random.Next(0, 400);
				Enemy enemy = new Enemy(new Vector2(x, y));
				enemy.Texture = enemyTexture;
				enemies.Add(enemy);
			}
		}

		/// <summary>
		/// Update Enemies and player status
		/// </summary>
		/// <param name="gameTime">Provide a snapshot of time value</param>
		public void Update(GameTime gameTime) {
			GenerateEnemies();
			for (int i = 0; i < enemies.Count; i++) {
				if (enemies[i].IsAlive) {
					if (enemies[i].AlphaValue < 255 && enemies[i].IsSpawned == false) {
						enemies[i].FadeIn(enemies[i].FadeInStep);
					}
					else {
						enemies[i].IsSpawned = true;
						//đếm khi nào đủ số giay delay thì dừng
						enemies[i].FadeDelayCounter += gameTime.ElapsedGameTime.TotalSeconds;
						if (enemies[i].FadeDelayCounter >= enemies[i].DelayAfterFadeIn) {
							enemies[i].FadeOut(enemies[i].FadeOutStep);
						}
					}
				}
				else {
					enemies[i].FadeOut(enemies[i].FadeOutStep);
				}
				//Remove enemy from the list if it's totally fade out. Also increase player Coin
				if (enemies[i].AlphaValue < 0) {
					player.Coin += enemies[i].Coin;
					enemies.Remove(enemies[i]);
				}
			}
		}

		/// <summary>
		/// Draw the game's screen.
		/// </summary>
		/// <param name="totalElapsedSeconds">The total seconds elapsed since the game started.</param>
		public void Draw() {
			spriteBatch.Begin();
			DrawBackground();
			spriteBatch.End();
			
			spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied);
			DrawEnemies();
			DrawHUD();

			spriteBatch.End();
		}

		/// <summary>
		/// Ve Hinh nen cua game
		/// </summary>
		/// <param name="totalElapsedSeconds"></param>
		private void DrawBackground() {
			spriteBatch.Draw(background, gameWorldBounds, Color.White);
		}

		/// <summary>
		/// Ve cac thong tin hien thi tren man hinh
		/// </summary>
		private void DrawHUD() {
			spriteBatch.DrawString(coinFont, player.Coin.ToString(), new Vector2(700, 10), Color.NavajoWhite);
		}

		/// <summary>
		/// How to draw enemies
		/// </summary>
		private void DrawEnemies() {
			touchCollection = TouchPanel.GetState();
			foreach (var touch in touchCollection) {
				touchPosition = touch.Position;
			}
			foreach (var enemy in enemies) {
				enemy.AlphaValue = enemy.SetAlphaValue();
				CheckEnemyStatus(enemy, touchPosition.X, touchPosition.Y);
				spriteBatch.Draw(enemy.Texture, new Rectangle((int)enemy.Position.X, (int)enemy.Position.Y, (int)enemy.Width/2, (int)enemy.Height/2), new Rectangle(0, 0, (int)enemy.Width, (int)enemy.Height), new Color(255, 255, 255, (byte)enemy.AlphaValue));
			}
		}

		/// <summary>
		/// Kiem tra trang thai cua 1 enemy co bi chem hay chua
		/// </summary>
		/// <param name="enemy">Doi tuong duoc xem xet</param>
		/// <param name="x">Toa do X cua gesture</param>
		/// <param name="y">Toa do y cua gesture</param>
		private void CheckEnemyStatus(Enemy enemy, float x, float y) {
			if (x >= enemy.Position.X &&
				x <= enemy.Position.X + enemy.Width &&
				y >= enemy.Position.Y &&
				y <= enemy.Position.Y + enemy.Height) {
				enemy.IsAlive = false;
			}
		}

		#region Do not touch yet
		public XmlSchema GetSchema() {
			return null;
		}

		public void ReadXml(XmlReader reader) { }
		public void WriteXml(XmlWriter writer) { }
		#endregion
	}
}
